'use strict';
// Copyright 2014 Blueant Inc. All Rights Reserved.

/**
 * @fileoverview 角色
 * @author sundbcn@gmail.com (sun debing)
 */

var _ = require('lodash');
var moment = require('moment');
var async = require('async');
var mongoConnector = require('../libs/mongodb/mongoConnector');
var activityModel = require('./activityModel');
/* jshint unused:false */
var roleSchema = require('../schemas/roleSchema');
var Role = mongoConnector().model('Role');
var vipConf = require('../config/vipConf.js');
var constantUtil = require('../util/constantUtil');
var arenaModel = require('./arenaModel.js');
var skillConf = require('../config/skillConf');
var skillService = require('../services/skillService.js');
var PlayerManager = require('../libs/playerManager.js');
var soldierService = require('../services/soldierService.js');

/**
 * 获取角色列表
 */
module.exports.getRoleList = function (uid, cb) {
    Role.find({
        uid: uid
    }, cb);
};

/**
 * 更新联盟旗帜信息
 */
module.exports.updateUnionFlag = function (union_id, union_flag, cb) {
    Role.update({
        union_id: union_id
    }, {
        $set: {
            union_flag: union_flag
        }
    }, {
        multi: true
    }, function (err, list) {
        cb();
    });
};

/**
 * 更新联盟名字信息
 */
module.exports.updateUnionName = function (union_id, union_name, cb) {
    Role.update({
        union_id: union_id
    }, {
        $set: {
            union_name: union_name
        }
    }, {
        multi: true
    }, cb);
};

/**
 * 获取角色列表
 */
module.exports.findRoles = function (where, cb) {
    Role.find(where, cb);
};

/**
 * 根据role_id获取角色
 * @return {[type]} [description]
 */
module.exports.getByRoleId = function (role_id, cb) {
    if (!role_id) {
        return cb(new Error('role_id undefined'));
    }
    Role.findOne({
        role_id: role_id
    }, function (err, role_model) {
        if (!!err) {
            console.error(err);
            return cb(err);
        }
        if (!role_model) {
            return cb(new Error('role not exist: ' + role_id.toString()));
        }
        cb(null, role_model);
    });
};

/**
 * 5点刷新
 */
module.exports.onFiveRefresh = function (self, cb) {
    // 每日累计充值，当天已领取每日累计充值奖励
    self.daily_pay = 0;
    self.daily_pay_picked = [];

    // 重置掠夺次数
    var vip_num = vipConf.getConf(self.getVip()).add_pvp_reward_times;
    var reward_time_limit = constantUtil.value('pvp_reward_time_limit') + vip_num;
    var pvp_lose_star_limit = constantUtil.value('pvp_lose_star_limit');

    if (self.harry_count < reward_time_limit) {
        self.harry_count = reward_time_limit;
    }

    if (self.harry_dragon_count < reward_time_limit) {
        self.harry_dragon_count = reward_time_limit;
    }

    if (self.harry_less_count < pvp_lose_star_limit) {
        self.harry_less_count = pvp_lose_star_limit;
    }

    // 重置购买次数(金币、粮食、体力)
    self.resetLimitTime(self);

    cb();
};

/**
 * 刷新数据
 */
module.exports.onRefreshData = function (self, callback) {
    async.waterfall(
        [
            // function (cb) {
            //     // 刷新繁荣度
            //     _refreshProsperous(self, cb);
            // },
            function (cb) {
                // 刷新体力
                _refreshEnergy(self, cb);
            },
            function (cb) {
                // 等级变化处理
                _levelUpProc(self, cb);
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
                return callback();
            }
            callback();
        }
    );
};

// 刷新繁荣度
var _refreshProsperous = function (self, cb) {
    self.refreshProsperous();
    cb();
};

/**
 * 根据用户名获取角色
 */
module.exports.getByName = function (name, cb) {
    Role.findOne({
        name: name
    }, cb);
};

/**
 * 根据名字关键字获取角色
 */
module.exports.getRoleByNameKeyWord = function (word, cb) {
    Role.find({
            name: {
                $regex: word
            }
        })
        .limit(10)
        .select('role_id vip')
        .exec(cb);
};

/**
 * 根据职业获取角色
 */
module.exports.getByJob = function (uid, job_type, cb) {
    Role.findOne({
        uid: uid,
        job_type: job_type
    }, cb);
};

/**
 * 创建角色
 */
module.exports.createRole = function (uid, channel_id, job_type, name, cb) {
    Role.create({
        uid: uid,
        channel_id: channel_id,
        job_type: job_type,
        name: name,
        recruits: 1
    }, cb);
};

/**
 * 获取当前等級段玩家排名
 */
module.exports.getLevelRank = function (role_id, begin_lv, lv, cb) {
    var count;
    var other_count;
    async.series(
        [
            function (cb) {
                Role.where('lv')
                    .gte(begin_lv)
                    .lt(lv)
                    .count(
                        function (err, num) {
                            count = num;
                            cb();
                        });
            },
            function (cb) {
                Role.where('lv')
                    .equals(lv)
                    .where('role_id')
                    .lt(role_id)
                    .count(
                        function (err, num) {
                            other_count = num + 1;
                            cb();
                        });
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
            }
            cb(null, count + other_count);
        }
    );
};

/**
 * 获取当前玩家等級排名
 */
module.exports.getCurrentRoleLevelRank = function (role_id, lv, cb) {
    var count;
    var other_count;
    async.series(
        [
            function (cb) {
                Role.where('lv')
                    .gt(lv)
                    .count(
                        function (err, num) {
                            count = num;
                            cb();
                        });
            },
            function (cb) {
                Role.where('lv')
                    .equals(lv)
                    .where('role_id')
                    .lt(role_id)
                    .count(
                        function (err, num) {
                            other_count = num + 1;
                            cb();
                        });
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
            }
            cb(null, count + other_count);
        }
    );
};

/**
 * 获取当前玩家军功排名
 */
module.exports.getCurrentRoleHonorRank = function (role_id, honor, cb) {
    var count;
    var other_count;
    async.series(
        [
            function (cb) {
                Role.where('honor')
                    .gt(honor)
                    .count(
                        function (err, num) {
                            count = num;
                            cb();
                        });
            },
            function (cb) {
                Role.where('honor')
                    .equals(honor)
                    .where('role_id')
                    .gt(role_id)
                    .count(
                        function (err, num) {
                            other_count = num + 1;
                            cb();
                        });
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
            }
            cb(null, count + other_count);
        }
    );
};

module.exports.getTopFiftyLevelRank = function (cb) {
    Role.find({})
        .sort('-lv')
        .sort('role')
        .limit(50)
        .select('role_id job_type name lv union_id')
        .exec(cb);
};

module.exports.getHonorRank = function (row_count, cb) {
    Role.find({})
        .sort('-honor')
        .sort('role')
        .limit(row_count)
        .select('role_id job_type name lv union_id honor')
        .exec(cb);
};

var MIN_NOBLE = 1;
var MAX_NOBLE = 17;
/**
 * 根据官阶列表获取角色
 */
module.exports.getRoleByNobleListNotInProtect = function (noble, filter_role_id_list, find_limit, cb) {
    if (noble < MIN_NOBLE || noble > MAX_NOBLE) {
        return cb(null, []);
    }

    Role.find({
            // protect_end_time: {
            //     $lte: Date.now()
            // },
            role_id: {
                $nin: filter_role_id_list
            },
            noble: noble,
            recruits: 0
        })
        .select('role_id lv')
        .limit(find_limit)
        .sort({
            protect_end_time: 1
        })
        .exec(cb);
};

/**
 * 根据等级获取角色列表
 */
module.exports.getRoleListByLevel = function (role_id, role_lv, cb) {
    Role.find({
            lv: role_lv,
            role_id: {
                $ne: role_id
            }
        })
        .limit(5)
        .select('role_id name lv job_type last_login_time lv')
        .exec(cb);
};

module.exports.getAllRoleList = function (cb) {
    Role.find({})
        .select('role_id')
        .exec(cb);
};

/**
 * 根据等级区间获取推荐角色列表
 */
module.exports.getRoleListByLevelSection = function (
    min_begin_lv,
    min_end_lv,
    max_begin_lv,
    max_end_lv,
    limit_num,
    cb) {
    Role.find({})
        .or([{
            lv: {
                $gte: min_begin_lv,
                $lte: min_end_lv
            }
        }, {
            lv: {
                $gte: max_begin_lv,
                $lte: max_end_lv
            }
        }])
        .limit(limit_num)
        .select('role_id name lv job_type last_login_time lv')
        .exec(cb);
};

/**
 * 获取每个等级的区间的人
 */
module.exports.getLevelList = function (begin_lv, end_lv, cb) {
    Role.aggregate({
        $match: {
            lv: {
                $gte: begin_lv,
                $lte: end_lv
            }
        }
    }, {
        $project: {
            role_id: 1,
            lv: 1
        }
    }, {
        $group: {
            _id: '$lv',
            count: {
                $sum: 1
            }
        }
    }, cb);
};

module.exports.getRoleInfoByRoleId = function (role_id, cb) {
    Role.findOne({
        role_id: role_id
    }, function (err, role_model) {
        if (!!err || !role_model) {
            return cb();
        }
        cb(null, {
            uid: role_model.getUid(),
            role_id: role_model.getRoleId(),
            name: role_model.getName(),
            gold: role_model.getGold(),
            diamond: role_model.getDiamond(),
            food: role_model.getFood(),
            last_login_time: moment(role_model.getLastLoginTime()).unix(),
            last_logout_time: moment(role_model.getLastLogoutTime()).unix()
        });
    });
};

/**
 * 根据角色名获取角色信息
 */
module.exports.getRoleInfoByName = function (name, cb) {
    Role.findOne({
        name: name
    }, function (err, role_model) {
        if (!!err || !role_model) {
            return cb(null, {});
        }
        cb(null, {
            role_id: role_model.getRoleId(),
            name: role_model.getName(),
            gold: role_model.getGold(),
            diamond: role_model.getDiamond(),
            food: role_model.getFood()
        });
    });
};

module.exports.getRoleLv = function (role_id, cb) {
    Role.findOne({
        role_id: role_id
    }, function (err, role_model) {
        if (!!err || !role_model) {
            return cb(null, 1);
        }
        cb(null, role_model.getLv());
    });
};

/**
 * 解散聯盟
 */
module.exports.dismiss = function (union_id, cb) {
    Role.update({
        union_id: union_id
    }, {
        union_id: 0
    }, {
        multi: true
    }, function (err, raw) {
        cb();
    });
};

/**
 * 设置登陆时间
 */
module.exports.login = function (role_id, cb) {
    var query = {
        role_id: role_id
    };
    var options = {};
    var update = {
        last_login_time: Date.now()
    };
    Role.findOneAndUpdate(query, update, options, function (err) {
        if (!!err) {
            console.error(err);
        }
        cb();
    });
};

/**
 * 登出
 * @param  {[type]}   role_id [description]
 * @param  {Function} cb  [description]
 * @return {[type]}       [description]
 */
module.exports.logout = function (role_id, cb) {
    var query = {
        role_id: role_id
    };
    var options = {};
    Role.findOneAndUpdate(query, {
        last_logout_time: Date.now()
    }, options, function (err) {
        if (!!err) {
            console.error(err);
        }
        cb();
    });
};

/**
 * 体力回复
 * @param  {[type]} role_model [description]
 * @return {[type]}            [description]
 */
var _refreshEnergy = function (role_model, cb) {
    var curr_energy = role_model.getEnergy();
    var max_energy = role_model.getEnergyMax();
    if (curr_energy >= max_energy) {
        return cb();
    }
    var recover_seconds = moment().diff(moment(role_model.getEnergyRecoverTime()), 's');
    var sp_recover_time = constantUtil.value('sp_recover_time');
    if (recover_seconds < sp_recover_time) {
        return cb();
    }
    var add_energy = Math.floor(recover_seconds / sp_recover_time);
    if (add_energy <= 0) {
        return cb();
    }
    if (add_energy > max_energy - curr_energy) {
        add_energy = max_energy - curr_energy;
    }

    role_model.addEnergy(add_energy);
    if (role_model.getEnergy() >= role_model.getEnergyMax()) {
        role_model.last_recover_time = moment();
    } else {
        role_model.last_recover_time = moment(role_model.last_recover_time).add(sp_recover_time * add_energy, 's');
    }

    cb();
};

// 等级变化处理
var _levelUpProc = function (self, callback) {
    if (self.sync_lv >= self.lv) {
        return callback();
    }
    self.sync_lv = self.lv;

    async.waterfall(
        [
            function (cb) {
                // 竞技场开启
                _doOpenArena(self, cb);
            },
            function (cb) {
                // 英雄技能开启
                _doHeroSkill(self, cb);
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
                return callback();
            }
            callback();
        }
    );
};

// 开启竞技场
var _doOpenArena = function (role_model, next) {
    var arena_need_hero_lvl = constantUtil.value('arena_need_hero_lvl');
    if (role_model.getLv() < arena_need_hero_lvl) {
        return next();
    }

    var player_manager = role_model.mgr;
    if (!player_manager) {
        player_manager = new PlayerManager(role_model.role_id);
        player_manager.role = role_model;
    }

    var arena_model;
    async.waterfall(
        [
            function (cb) {
                player_manager.getModel(['arena', 'soldier'], cb);
            },
            function (cb) {
                arena_model = player_manager.arena;
                if (arena_model.rank > 0) {
                    return next();
                }
                var soldier_model = player_manager.soldier;
                var soldier_type_list = soldier_model.select_soldier_list;
                arena_model.setSoldierList(1, soldier_type_list);
                arena_model.setSoldierList(2, soldier_type_list);
                arena_model.att_power = soldierService.calcSoldierPower(soldier_model, soldier_type_list);
                arena_model.def_power = soldierService.calcSoldierPower(soldier_model, soldier_type_list);

                arenaModel.getNextRank(function (err, next_rank) {
                    arena_model.rank = next_rank;
                    arena_model.max_rank = next_rank;
                    cb();
                });
            },
            function (cb) {
                arena_model.refreshShop();
                cb();
            }
        ],
        function (err) {
            if (!!err) {
                console.error(err);
                return next();
            }
            next();
        }
    );
};

// 开启英雄技能
var _doHeroSkill = function (role_model, next) {
    var player_manager = role_model.mgr;
    if (!player_manager) {
        player_manager = new PlayerManager(role_model.role_id);
        player_manager.role = role_model;
    }

    async.waterfall(
        [
            function (cb) {
                player_manager.getModel(['skill'], cb);
            },
            function (cb) {
                var skill_model = player_manager.skill;

                var job_type = role_model.getJob();
                var hero_lv = role_model.getLv();
                var skill_list = skillConf.getJobCanOpenSkillList(job_type, hero_lv);
                var skill_changed = false;
                _.each(skill_list, function (skill_id) {
                    if (skill_model.addSkill(skill_id)) {
                        skill_changed = true;
                    }
                });

                if (skill_changed) {
                    // 刷新战力
                    skillService.updateSkillPower(player_manager);
                    cb();
                } else {
                    cb();
                }
            }
        ],
        function (err) {
            return next();
        }
    );
};
